using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 产品管理接口
    /// 提供产品的增删改查、库存管理、推荐设置等功能的 RESTful API
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    [Authorize]
    public class ProductsController : ControllerBase
    {
        private readonly IProductAppService _productService;
        private readonly ILogger<ProductsController> _logger;

        public ProductsController(
            IProductAppService productService,
            ILogger<ProductsController> logger)
        {
            _productService = productService;
            _logger = logger;
        }

        /// <summary>
        /// 获取分页产品列表
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="keyword">搜索关键词</param>
        /// <param name="categoryId">分类ID</param>
        /// <param name="status">产品状态</param>
        /// <param name="minPrice">最低价格</param>
        /// <param name="maxPrice">最高价格</param>
        /// <param name="sortBy">排序字段</param>
        /// <param name="sortDesc">是否降序</param>
        /// <returns>分页产品列表</returns>
        [HttpGet]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<PagedResultDto<ProductDto>>> GetPaged(
            [FromQuery] int pageIndex = 1,
            [FromQuery] int pageSize = 20,
            [FromQuery] string? keyword = null,
            [FromQuery] long? categoryId = null,
            [FromQuery] byte? status = null,
            [FromQuery] decimal? minPrice = null,
            [FromQuery] decimal? maxPrice = null,
            [FromQuery] string? sortBy = null,
            [FromQuery] bool sortDesc = false)
        {
            try
            {
                var (items, total) = await _productService.GetPagedAsync(pageIndex, pageSize, keyword, categoryId, status, minPrice, maxPrice, sortBy, sortDesc);
                return Ok(new PagedResultDto<ProductDto>(items, total, pageIndex, pageSize));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting paged products");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取所有产品
        /// </summary>
        /// <returns>产品列表</returns>
        [HttpGet("all")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ProductDto>>> GetAll()
        {
            try
            {
                var result = await _productService.GetAllAsync();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting all products");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 根据ID获取产品
        /// </summary>
        /// <param name="id">产品ID</param>
        /// <returns>产品信息</returns>
        [HttpGet("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        [AllowAnonymous]
        public async Task<ActionResult<ProductDto>> GetById(long id)
        {
            try
            {
                var result = await _productService.GetByIdAsync(id);
                if (result == null) return NotFound();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting product {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 根据SKU获取产品
        /// </summary>
        /// <param name="sku">产品SKU</param>
        /// <returns>产品信息</returns>
        [HttpGet("sku/{sku}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        [AllowAnonymous]
        public async Task<ActionResult<ProductDto>> GetBySku(string sku)
        {
            try
            {
                var result = await _productService.GetBySkuAsync(sku);
                if (result == null) return NotFound();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting product by sku {Sku}", sku);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 根据Slug获取产品
        /// </summary>
        /// <param name="slug">产品Slug</param>
        /// <returns>产品信息</returns>
        [HttpGet("slug/{slug}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        [AllowAnonymous]
        public async Task<ActionResult<ProductDto>> GetBySlug(string slug)
        {
            try
            {
                var result = await _productService.GetBySlugAsync(slug);
                if (result == null) return NotFound();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting product by slug {Slug}", slug);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 根据分类获取产品
        /// </summary>
        /// <param name="categoryId">分类ID</param>
        /// <returns>产品列表</returns>
        [HttpGet("category/{categoryId:long}")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ProductDto>>> GetByCategory(long categoryId)
        {
            try
            {
                var result = await _productService.GetByCategoryAsync(categoryId);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting products by category {CategoryId}", categoryId);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取推荐产品
        /// </summary>
        /// <param name="count">返回数量</param>
        /// <returns>推荐产品列表</returns>
        [HttpGet("featured")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ProductDto>>> GetFeatured([FromQuery] int count = 10)
        {
            try
            {
                var result = await _productService.GetFeaturedProductsAsync(count);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting featured products");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取热销产品
        /// </summary>
        /// <param name="count">返回数量</param>
        /// <returns>热销产品列表</returns>
        [HttpGet("best-selling")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ProductDto>>> GetBestSelling([FromQuery] int count = 10)
        {
            try
            {
                var result = await _productService.GetBestSellingProductsAsync(count);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting best selling products");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取最新产品
        /// </summary>
        /// <param name="count">返回数量</param>
        /// <returns>最新产品列表</returns>
        [HttpGet("latest")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ProductDto>>> GetLatest([FromQuery] int count = 10)
        {
            try
            {
                var result = await _productService.GetLatestProductsAsync(count);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting latest products");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取库存不足的产品
        /// </summary>
        /// <param name="threshold">库存阈值</param>
        /// <returns>库存不足的产品列表</returns>
        [HttpGet("low-stock")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ProductDto>>> GetLowStock([FromQuery] int threshold = 10)
        {
            try
            {
                var result = await _productService.GetLowStockProductsAsync(threshold);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting low stock products");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 搜索产品
        /// </summary>
        /// <param name="keyword">关键词</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <returns>搜索结果</returns>
        [HttpGet("search")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<PagedResultDto<ProductDto>>> Search(
            [FromQuery] string keyword,
            [FromQuery] int pageIndex = 1,
            [FromQuery] int pageSize = 20)
        {
            try
            {
                var (items, total) = await _productService.SearchAsync(keyword, pageIndex, pageSize);
                return Ok(new PagedResultDto<ProductDto>(items, total, pageIndex, pageSize));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error searching products with keyword {Keyword}", keyword);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 创建产品
        /// </summary>
        /// <param name="dto">产品数据</param>
        /// <returns>创建的产品</returns>
        [HttpPost]
        [ProducesResponseType(201)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<ProductDto>> Create([FromBody] ProductDto dto)
        {
            try
            {
                var created = await _productService.CreateAsync(dto);
                return CreatedAtAction(nameof(GetById), new { id = created.Id }, created);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating product");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 更新产品
        /// </summary>
        /// <param name="id">产品ID</param>
        /// <param name="dto">产品数据</param>
        /// <returns>更新的产品</returns>
        [HttpPut("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<ProductDto>> Update(long id, [FromBody] ProductDto dto)
        {
            try
            {
                dto.Id = id;
                var updated = await _productService.UpdateAsync(dto);
                return Ok(updated);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating product {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 删除产品
        /// </summary>
        /// <param name="id">产品ID</param>
        /// <returns>删除结果</returns>
        [HttpDelete("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        public async Task<ActionResult<object>> Delete(long id)
        {
            try
            {
                var ok = await _productService.DeleteAsync(id);
                if (!ok) return NotFound();
                return Ok(new { success = true });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting product {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 批量删除产品
        /// </summary>
        /// <param name="request">批量删除请求</param>
        /// <returns>删除结果</returns>
        [HttpPost("batch-delete")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> BatchDelete([FromBody] BatchDeleteRequest request)
        {
            try
            {
                var count = await _productService.BatchDeleteAsync(request.Ids);
                return Ok(new { success = true, count });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error batch deleting products");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 更新产品状态
        /// </summary>
        /// <param name="id">产品ID</param>
        /// <param name="status">状态值</param>
        /// <returns>更新结果</returns>
        [HttpPost("{id:long}/status")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> UpdateStatus(long id, [FromQuery] byte status)
        {
            try
            {
                var ok = await _productService.UpdateStatusAsync(id, status);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating product status {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 更新产品库存
        /// </summary>
        /// <param name="id">产品ID</param>
        /// <param name="stock">库存数量</param>
        /// <returns>更新结果</returns>
        [HttpPost("{id:long}/stock")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> UpdateStock(long id, [FromQuery] int stock)
        {
            try
            {
                var ok = await _productService.UpdateStockAsync(id, stock);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating product stock {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 增加产品库存
        /// </summary>
        /// <param name="id">产品ID</param>
        /// <param name="quantity">增加数量</param>
        /// <returns>更新结果</returns>
        [HttpPost("{id:long}/stock/increase")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> IncreaseStock(long id, [FromQuery] int quantity)
        {
            try
            {
                var ok = await _productService.IncreaseStockAsync(id, quantity);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error increasing product stock {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 减少产品库存
        /// </summary>
        /// <param name="id">产品ID</param>
        /// <param name="quantity">减少数量</param>
        /// <returns>更新结果</returns>
        [HttpPost("{id:long}/stock/decrease")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> DecreaseStock(long id, [FromQuery] int quantity)
        {
            try
            {
                var ok = await _productService.DecreaseStockAsync(id, quantity);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error decreasing product stock {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 增加产品销量
        /// </summary>
        /// <param name="id">产品ID</param>
        /// <param name="quantity">增加数量</param>
        /// <returns>更新结果</returns>
        [HttpPost("{id:long}/sales/increment")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> IncrementSales(long id, [FromQuery] int quantity = 1)
        {
            try
            {
                var ok = await _productService.IncrementSalesCountAsync(id, quantity);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error incrementing sales count for product {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 检查SKU是否存在
        /// </summary>
        /// <param name="sku">SKU编码</param>
        /// <param name="excludeId">排除的产品ID</param>
        /// <returns>是否存在</returns>
        [HttpGet("sku-exists")]
        [ProducesResponseType(200)]
        public async Task<ActionResult<object>> SkuExists([FromQuery] string sku, [FromQuery] long? excludeId = null)
        {
            try
            {
                var exists = await _productService.SkuExistsAsync(sku, excludeId);
                return Ok(new { exists });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error checking sku exists {Sku}", sku);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 检查Slug是否存在
        /// </summary>
        /// <param name="slug">Slug值</param>
        /// <param name="excludeId">排除的产品ID</param>
        /// <returns>是否存在</returns>
        [HttpGet("slug-exists")]
        [ProducesResponseType(200)]
        public async Task<ActionResult<object>> SlugExists([FromQuery] string slug, [FromQuery] long? excludeId = null)
        {
            try
            {
                var exists = await _productService.SlugExistsAsync(slug, excludeId);
                return Ok(new { exists });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error checking slug exists {Slug}", slug);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取产品统计信息
        /// </summary>
        /// <returns>统计数据</returns>
        [HttpGet("statistics")]
        [ProducesResponseType(200)]
        public async Task<ActionResult<object>> GetStatistics()
        {
            try
            {
                var stats = await _productService.GetStatisticsAsync();
                return Ok(stats);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting product statistics");
                return BadRequest(new { message = ex.Message });
            }
        }
    }
}
